package com.itheima.controller;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.itheima.commen.Result;
import com.itheima.dto.MenuDto;
import com.itheima.pojo.Permission;
import com.itheima.pojo.PermissionMenuExtend;
import com.itheima.pojo.PermissionPermissionGroup;
import com.itheima.pojo.PermissionPointExtend;
import com.itheima.service.PermissionMenuExtendService;
import com.itheima.service.PermissionPermissionGroupService;
import com.itheima.service.PermissionPointExtendService;
import com.itheima.service.PermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@Slf4j
public class MenuController {
    @Autowired
        private PermissionService permissionService;
    @Autowired
        private PermissionMenuExtendService permissionMenuExtendService;
    @Autowired
        private PermissionPointExtendService permissionPointExtendService;
    @Autowired
        private PermissionPermissionGroupService permissionPermissionGroupService;

    //菜单回显详情
    @GetMapping("/menus/{id}")
    public MenuDto getById(@PathVariable Integer id){
        Permission permission = permissionService.getById(id);
        String s = JSON.toJSONString(permission);
        MenuDto menuDto = JSON.parseObject(s, MenuDto.class);
        System.out.println("--------menuDto:"+menuDto);
        String code=null;
        Byte type = permission.getType();
        if (type==1) {
            menuDto.setIs_point(false);
            code = permissionMenuExtendService.getCodeByPid(permission.getPermissionMenuExtendId());
        }else if (type==2){
            menuDto.setIs_point(true);
            code = permissionPointExtendService.getCodeByPid(permission.getPermissionPointExtendId());
        }
        menuDto.setCode(code);
        menuDto.setTitle(permission.getName());
        return menuDto;

    }

    //菜单修改
    @PutMapping("/menus/{id}")
    public Result update(@PathVariable Long id, @RequestBody MenuDto menuDto ){
        //1.更新permission的CreateTime,Name,Pid //type无权限更改
        if (id == menuDto.getPid()) {//自己不能挂自己
            return Result.error("修改失败");
        }
        Permission permission = permissionService.getById(menuDto.getId());
        permission.setCreateTime(new Date());
        permission.setPid(menuDto.getPid());
        permission.setName(menuDto.getTitle());
        //主导航pid必须为null;(上线第一版更新)
        Long pid = menuDto.getPid();
        if (pid==0) {
            permission.setPid(null);
        }
        log.info("更新permission{}",permission);
        boolean b = permissionService.updateById(permission);
        if (b) {
            log.info("更新permission成功!");
        }else {log.info("更新permission失败!"); }

        //更新id对应的code,
        boolean update=false;
        if (permission.getType()==1) {
            LambdaUpdateWrapper<PermissionMenuExtend> luw=new LambdaUpdateWrapper<>();
            luw.eq(PermissionMenuExtend::getPermissionId,menuDto.getId());
            luw.set(PermissionMenuExtend::getCode,menuDto.getCode());
            update = permissionMenuExtendService.update(luw);
        }else if (permission.getType()==2){
            LambdaUpdateWrapper<PermissionPointExtend> luw=new LambdaUpdateWrapper<>();
            luw.eq(PermissionPointExtend::getPermissionId,menuDto.getId());
            luw.set(PermissionPointExtend::getCode,menuDto.getCode());
            update = permissionPointExtendService.update(luw);
        }
        if (update) {
            log.info("code更新成功!");
        }else {log.info("code更新失败!");}
        return null;
    }

    //菜单列表
    @GetMapping("/menus")
    public List<MenuDto> menuList(){
        List<Permission> permissionList = permissionService.list();
        List<MenuDto> menuChildsDtos=new ArrayList<>();
        List<Permission> perSonList=new ArrayList<>();
        for (Permission permission : permissionList) {
            //1.遍历找出子级目录,用于递归
            if (permission.getPid() != null) {
                perSonList.add(permission);
            }
        }
        for (Permission permission : permissionList) {
            //1.找出1级目录,放入childsDto
            /*设置
            is_point;
            title;
            code;
            */
            //2.遍历找出一级目录
            //2.找出childs的二级目录,放入childsDto的childs
            if (permission.getPid() == null) {
                //复制对象
                String s = JSON.toJSONString(permission);
                MenuDto menuChildsDto = JSON.parseObject(s, MenuDto.class);
                   //设置 title
                menuChildsDto.setTitle(permission.getName());
                   //设置CreateTime
                menuChildsDto.setCreateTime(new Date());
                //设置code;
                menuChildsDto.setCode(getCode(menuChildsDto));

                List<MenuDto> list = getList(menuChildsDto, perSonList);
                menuChildsDto= setPointOrChilds(permission,menuChildsDto,list);
                //设置list
                log.info("menuChildsDto{}",menuChildsDto);
                menuChildsDtos.add(menuChildsDto);
            }
        }

        return menuChildsDtos;
        }
    //菜单删除
    @DeleteMapping("/menus/{id}")
    public Result deleteMenu(@PathVariable Integer id){
        //1.删除从表code表,触发数据库删除主表Permission表,
        //2.删除权限组表
        // Permission是主表 应该先删除从表code表,直接删除主表会报错
        //注意:将sql数据库中--设计表--外键--删除时/更新时--
        //     设置为"CASCADE"表示删除从表操作触发删除主表对应外键
        Permission permission = permissionService.getById(id);

        //先删除对应的Permission主表报错
        boolean b = permissionService.removeById(id);
        if (b) {
            log.info("Permission删除成功!");
        }else {
            log.info("Permission删除失败!");
        }
        //2.删除code从表,触发数据库删除关联外键主表
        Byte type = permission.getType();
        boolean remove=false;
        if (type==1) {
            remove = permissionMenuExtendService.removeById(permission.getPermissionMenuExtendId());
        }else if (type==2){
            remove=permissionPointExtendService.removeById(permission.getPermissionPointExtendId());
        }
        if (remove) {
            log.info("code删除成功!");
        }else {
            log.info("code删除失败!");
        }

        //2.删除权限组表
        LambdaUpdateWrapper<PermissionPermissionGroup> luw=new LambdaUpdateWrapper<>();
        luw.eq(PermissionPermissionGroup::getPid,id);
        boolean remove1 = permissionPermissionGroupService.remove(luw);
        if (remove1) {
            log.info("权限组对应权限删除成功!");
        }else {
            log.info("权限组对应权限删除失败!");
        }

        return null;
    }

    //菜单添加
    @PostMapping("/menus")
    public Result add(@RequestBody MenuDto menuDto){
        //{
        //    "pid": 166,
        //    "is_point": false,//对应type=2
        //    "code": "daima",
        //    "title": "添加菜单1",
        //    "id": ""
        //}
        //1.添加permission 2.添加code 3.修改permission中PointIDOrMenuID的关联键
        //1.先添加code,拿到piontId 或者menuid
        //
        Boolean is_point = menuDto.getIs_point();

        Permission permission = new Permission();
        if (!is_point) {
            permission.setType((byte) 1);
        }else {
            permission.setType((byte) 2);
        }
        permission.setCreateTime(new Date());
        permission.setPid(menuDto.getPid());
        permission.setName(menuDto.getTitle());
        //主导航pid必须为null;(上线第一版更新)
        Long pid = menuDto.getPid();
        if (pid==0) {
            permission.setPid(null);
        }


        log.info("添加permission{}",permission);
        boolean save = permissionService.save(permission);
        if (save) {
            log.info("添加permission成功{}",permission);
        }else {
            log.info("添加permission失败{}",permission);
        }
        boolean save1;
        Long menuId = null;
        Long pointId =null;
        if (!is_point) {//存menu表
            PermissionMenuExtend permissionMenuExtend = new PermissionMenuExtend(
                    permission.getPermissionMenuExtendId(),
                    menuDto.getCode(),
                    permission.getId()
                    );
             save1= permissionMenuExtendService.save(permissionMenuExtend);
             //拿出MenuId,更新到permission
            menuId = permissionMenuExtend.getId();
        }else{//存piont表
            PermissionPointExtend permissionPointExtend =new PermissionPointExtend(
                    permission.getPermissionPointExtendId(),
                    menuDto.getCode(),
                    permission.getId()
            );
            save1=permissionPointExtendService.save(permissionPointExtend);
            //拿出PointId,更新到permission
            pointId = permissionPointExtend.getId();
        }
        if (save1) {
            log.info("添加PointOrMenu成功{}",permission);
        }else {
            log.info("添加PointOrMenu失败{}",permission);
        }
        //3.修改添加permission关联键
        LambdaUpdateWrapper<Permission> luw=new LambdaUpdateWrapper<>();
        luw.eq(Permission::getId,permission.getId());
        luw.set(menuId!=null,Permission::getPermissionMenuExtendId,menuId);
        luw.set(pointId!=null,Permission::getPermissionPointExtendId,pointId);
        permissionService.update(luw);
        return null;
    }




    private MenuDto setPointOrChilds(Permission permission, MenuDto menuChildsDto, List<MenuDto> list) {
        Byte type = permission.getType();
        //设置is_point;
        if (type == 1) {
            menuChildsDto.setChilds(list);
            menuChildsDto.setIs_point(false);
        } else {
            menuChildsDto.setPoints(list);
            menuChildsDto.setIs_point(true);
        }
        return menuChildsDto;
    }

    private List<MenuDto> getList(MenuDto menuChildsDto, List<Permission> perSonList) {
        List<MenuDto> menuDtoList=perSonList.stream().filter(permission ->
            permission.getPid().equals(menuChildsDto.getId())
            //父级目录id对应的子级对象
        ).map(permission -> {
            String s = JSON.toJSONString(permission);
            MenuDto menuDto = JSON.parseObject(s, MenuDto.class);
            //设置 title
            menuDto.setTitle(permission.getName());
            //设置CreateTime
            menuDto.setCreateTime(new Date());
            //设置code;
            menuDto.setCode(getCode(menuDto));

            Byte type = permission.getType();
            if (type==1) {
                menuDto.setChilds(getList(menuDto,perSonList));
                menuDto.setIs_point(false);
            }else {
                menuDto.setPoints(getList(menuDto,perSonList));
                menuDto.setIs_point(true);
            }
            //设置 title
            menuDto.setTitle(permission.getName());
            //设置CreateTime
            menuDto.setCreateTime(new Date());
            return menuDto;
        }).collect(Collectors.toList());
        return menuDtoList;
    }

    private String getCode( MenuDto menuChildsDto) {
        String code =null;
        if (menuChildsDto.getType()==1) {
            code = permissionMenuExtendService.getCodeByPid(menuChildsDto.getPermissionMenuExtendId());
        } else if (menuChildsDto.getType()==2) {
            log.info("Type==2,getPointExtendId:{}",menuChildsDto.getPermissionPointExtendId());
            code = permissionPointExtendService.getCodeByPid(menuChildsDto.getPermissionPointExtendId());
        }
        return code;
    }
}

